﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MarvellousWorks.PracticalPatternNet8.Concept.Delegating;

/// <summary>
/// 定义一个委托，表示带有两个整数参数和一个字典参数的方法签名。
/// </summary>
public delegate void MemoHandler(int x, int y, IDictionary<string, int> data);

/// <summary>
/// 智能委托调用器，通过反射和委托组合，将多个操作（加、减、乘）组合到一个委托链中。
/// </summary>
public class UglySmartDelegateInvoker
{
    // 使用 Action<int, int, IDictionary<string, int>> 代替 MemoHandler，便于与反射API配合。
    private readonly Action<int, int, IDictionary<string, int>> handler;

    /// <summary>
    /// 构造函数，动态创建并组合 Add、Sub、Mul 方法的委托。
    /// </summary>
    public UglySmartDelegateInvoker()
    {
        // 获取委托类型
        Type type = typeof(Action<int, int, IDictionary<string, int>>);
        // 创建 A.Add 的委托
        Delegate d = Delegate.CreateDelegate(type, new A(), "Add");
        // 组合 S.Sub 的委托
        d = Delegate.Combine(d, Delegate.CreateDelegate(type, new S(), "Sub"));
        // 组合 M.Mul 的委托
        d = Delegate.Combine(d, Delegate.CreateDelegate(type, new M(), "Mul"));
        // 转换为强类型委托
        handler = (Action<int, int, IDictionary<string, int>>)d;

        // 也可以用匿名方法追加委托，如下所示（已注释）：
        // handler += (x, y, data) => data["sum"] = x + y;
        // handler += (x, y, data) => data["diff"] = x - y;
        // handler += (x, y, data) => data["prod"] = x * y;
        // handler += (x, y, data) => data["quot"] = x / y;
    }

    /// <summary>
    /// 调用组合后的委托链，依次执行加、减、乘操作。
    /// </summary>
    /// <param name="x">第一个整数参数。</param>
    /// <param name="y">第二个整数参数。</param>
    /// <param name="data">用于存储结果的字典。</param>
    public void Invoke(int x, int y, IDictionary<string, int> data)
    {
        handler?.Invoke(x, y, data);
    }
}

/// <summary>
/// 提供加法操作。
/// </summary>
public class A
{
    /// <summary>
    /// 未被当前实现使用的重载方法。
    /// </summary>
    public void Add(int x, IDictionary<string, int> data)
    {
    }

    /// <summary>
    /// 计算 x + y，并将结果存入字典的 "add" 键。
    /// </summary>
    public void Add(int x, int y, IDictionary<string, int> data)
    {
        data["add"] = x + y;
    }
}

/// <summary>
/// 提供减法操作。
/// </summary>
public class S
{
    /// <summary>
    /// 未被当前实现使用的重载方法。
    /// </summary>
    public void Sub(int x, IDictionary<string, int> data)
    {
    }

    /// <summary>
    /// 计算 x - y，并将结果存入字典的 "sub" 键。
    /// </summary>
    public void Sub(int x, int y, IDictionary<string, int> data)
    {
        data["sub"] = x - y;
    }
}

/// <summary>
/// 提供乘法操作。
/// </summary>
public class M
{
    /// <summary>
    /// 未被当前实现使用的重载方法。
    /// </summary>
    public void Mul(int x, IDictionary<string, int> data)
    {
    }

    /// <summary>
    /// 计算 x * y，并将结果存入字典的 "mul" 键。
    /// </summary>
    public void Mul(int x, int y, IDictionary<string, int> data)
    {
        data["mul"] = x * y;
    }
}